//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "ia\fn_civilian.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_grp","_radius","_debug"];
DEFAULT_PARAM(_grp,0,grpNull);
DEFAULT_PARAM(_radius,1,300);
DEFAULT_PARAM(_switch_side,2,"");
DEFAULT_PARAM(_debug,3,false);

if (IS_OBJECT(_grp)) then {
	_grp = group _grp;
};
if (IS_GROUP(_grp) && {(count (units _grp)) > 0}) then {
	if (!isServer && !(local (leader _grp))) exitWith { ERROR_1("Execution should be on server or local to the unit",_this); };
	private ["_center","_units","_str_fnc","_pos","_wp","_i","_is_vec","_old_grp"];
	_center = getPos (leader _grp);
	_units = units _grp;
	if (!(IS_STRING(_switch_side)) || {_switch_side != ""}) then {
		_old_grp = _grp;
		_grp = [_switch_side] call FFUNC(createGroup);
		_units joinSilent _grp;
		DEBUG_2("Side Switched",_old_grp,_grp);
		[_old_grp] call FFUNC(deleteGroup);
	};
	_grp allowFleeing 1;
	_grp setBehaviour "SAFE";
	_grp setCombatMode "BLUE";
	_is_vec = false;
	{
		if (_x isKindOf "CAManBase") then {
			_x call FFUNC(disableAIScripts);
			_x addEventHandler ["Killed",{
				if (isPlayer(_this select 1)) then {
					[(_this select 1),-10] call FFUNC(addScore);
					[QGVAR(all_message),[["STR_TMF_KILLEDACIVILIAN",name(_this select 1)],"all",objNull,"hq"],THIS_FILE] call FFUNC(callEvent);
				};
				DEBUG_1("Civilian Killed",_this);
			}];
			_x addEventHandler ["FiredNear",FFUNC(civilianDanger)];
			_x addEventHandler ["Hit",FFUNC(civilianDanger)];
		};
		_is_vec = _is_vec || (vehicle _x != _x);
		if ((vehicle _x != _x) && {(driver (vehicle _x)) == _x}) then {
			(vehicle _x) addEventHandler ["handleDamage",{
				// Only pass on damage of vehicle caused by an ammunition
				if ((isPlayer(driver(_this select 0))) || isPlayer(_this select 3) || ((_this select 4) != "" && {isClass(configFile/"CfgAmmo"/(_this select 4))})) then {
					DEBUG_1("Combat Vehicle Damage",_this);
					(_this select 2)
				} else {
					DEBUG_1("Ignored Vehicle Damage",_this);
					0
				};
			}];
		};
	} foreach _units;
	
	[_grp] call FFUNC(deleteWaypoints);
	_str_fnc = format["[this,thisList] spawn %1",QUOTE(FFUNC(civilianWaypointCode))];
	if (!_is_vec) then {
		private ["_bldpos","_size"];
		// Case of units on foot
		if (_radius < ((count _units) * 25)) then {
			_radius = ((count _units) * 25);
		};
		_pos = _center;
		for "_i" from 0 to (14 max ((count _units) * 2)) do {
			_size = (_radius / 10);
			if (random(10) >= 4) then {
				_bldpos = [_pos,[TMF_BUILDING_POS_COMBAT,TMF_BUILDING_POS_DOOR], 30] call FFUNC(buildingPositions);
				if (count _bldpos > 0) then {
					_pos = (_bldpos call FFUNC(arrayRandomVal)) select 0;
					_size = 0;
				};
			};
			_wp = _grp addWaypoint [_pos,_size];
			_wp setWaypointType "MOVE";
			_wp setWaypointCompletionRadius 20;
			_wp setWaypointStatements ["true", _str_fnc];
			_pos = [_center,_radius] call FFUNC(getRanPointCircle);
		};
	} else {
		DEBUG_1("Is Vehicle",_units);
		// Case of units in vehicles
		private ["_road","_fnc_getRoad","_cnt","_tries","_added"];
		if (_radius < ((count _units) * 200)) then {
			_radius = ((count _units) * 200);
		};
		_fnc_getRoad = {
			private ["_center","_pos","_added","_radius","_roads","_tries","_dist","_road","_j","_fnc_filterInvisibleRoads"];
			_center = _this select 0;
			_radius = _this select 1;
			_added = _this select 2;
			_fnc_getRanPoint = {
				private ["_center","_radius","_added", "_i","_tries"];
				_center = _this select 0;
				_radius = _this select 1;
				_added = _this select 2;
				_pos = [];
				_tries = 0;
				while {count _pos <= 0 && _tries < 10} do {
					_pos = [_center,_radius] call FFUNC(getRanPointCircle);
					for "_i" from 0 to (count _added - 1) do {
						if (((_added select _i) distance _pos) < _radius / 6) exitWith { _pos = []; };
					};
					_tries = _tries + 1;
				};
				if (count _pos <= 0) then { [_center,_radius] call FFUNC(getRanPointCircle); };
				_pos;
			};
			
			_fnc_filterRoads = {
				// DEBUG_1("Found Roads",_this);
				private ["_k","_r"];
				_r = _this;
				if (count _this > 0) then {
					for "_k" from ((count _this) - 1) to 0 step -1 do {
						// DEBUG_1("Test Road",str((_this select _k)));
						// FUCKING ARMA 3 - Filter invisible roads used as concrete in bases... WHHHHYYYYYYYYYY??????????
						if (count (toArray(str((_this select _k)))) > 29 || {count (roadsConnectedTo (_this select _k)) < 2}) then {
							_r set [_k, "XxDeLxX"];
							_r = _r - ["XxDeLxX"];
						};
					};
					DEBUG_1("Filtered Roads",_r);
				};
				_r;
			};
			_pos = [_center,_radius,_added] call _fnc_getRanPoint;
			_roads = (_pos nearRoads 50) call _fnc_filterRoads;
			_road = objNull;
			_tries = 0;
			while { (count _roads) <= 0 && _tries < 30 } do {
				_pos = [_center,_radius,_added] call _fnc_getRanPoint;
				_roads = (_pos nearRoads 50) call _fnc_filterRoads;
				_tries = _tries + 1;
			};
			// DEBUG_1("GetRoad Find",ARR_2(_tries,_roads));
			if (count _roads > 0) then {
				_road = _roads call FFUNC(arrayRandomVal);
			};
			DEBUG_1("GetRoad",_road);
			_road;
		};
		_cnt = 0;
		_tries = 0;
		_added = [];
		for "_i" from 1 to (4 max ((count _units) * 2)) do {
			_road = [_center,_radius,_added] call _fnc_getRoad;
			_tries = _tries + 1;
			if (!(isNil "_road") && {!(isNull _road)}) then {
				_added set [count _added, getPos _road];
				_wp = _grp addWaypoint [getPos _road,1];
				_cnt = _cnt + 1;
				_wp setWaypointType "MOVE";
				_wp setWaypointCompletionRadius 100;
				_wp setWaypointStatements ["true", _str_fnc];
			} else {
				if (_cnt < 2 && _cnt < (count _units) && _tries < 50) then { _i = _i - 1; };
			};
		};
	};
	_grp setCurrentWaypoint [_grp,0];
	DEBUG_1("Group initialized",ARR_2(_grp,count(waypoints _grp)));
	if (_debug) then {
		private ["_mrk"];
		{
			_mrk = format["mrk_%1_%2",_grp,_foreachIndex];
			createMarker [_mrk, waypointPosition _x];
			_mrk setMarkerShape "ICON";
			_mrk setMarkerType "mil_dot";
			_mrk setMarkerColor "ColorCivilian";
			if (_is_vec) then {
				_mrk setMarkerType "mil_triangle";
			};
		} foreach (waypoints _grp);
	};
} else {
	ERROR_1("Invalid Input",_this);
};
TRACE("End");
TMFPROFILERSTOP;